package net.hn.hnms.biz.safety.location.company.service;

import lombok.RequiredArgsConstructor;
import net.hn.hnms.biz.api.mine.RemoteMineInfoService;
import net.hn.hnms.biz.api.mine.model.MineVo;
import net.hn.hnms.biz.api.safety.location.model.CompanyAlarmVo;
import net.hn.hnms.biz.api.safety.location.model.CompanyMonitoringVo;
import net.hn.hnms.biz.api.safety.location.model.CompanyRiskVo;
import net.hn.hnms.biz.api.safety.location.model.PeopleTrendVo;
import net.hn.hnms.biz.api.safety.monitor.model.Indicator;
import net.hn.hnms.sys.common.core.constant.Constants;
import net.hn.hnms.sys.common.core.domain.R;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 智呈物联 pan'sx
 * 2022/12/21 13:37
 * 1.0 version
 */
@Service
@RequiredArgsConstructor
public class CompanyLocationService {
    private final JdbcTemplate locationJdbcTemplate;
    private final RemoteMineInfoService remoteMineInfoService;

    public CompanyMonitoringVo monitoring() {
        CompanyMonitoringVo vo = new CompanyMonitoringVo();
        StringBuffer sql = new StringBuffer("select mine_code,count(1) from dwd_jxry_now_personnelinfo where flag_bit='1' GROUP BY mine_code ");
        List<Map<String, Object>> maps = locationJdbcTemplate.queryForList(sql.toString());
        AtomicInteger total = new AtomicInteger();
        maps.forEach(s -> {
            int count = Integer.parseInt(s.get("count").toString());
            total.set(total.get() + count);
            if (count >= 1000) {
                vo.setOverfiveHundredMine(vo.getOverStaffMine() + 1);
                vo.setOverThousandMine(vo.getOverThousandMine() + 1);
            } else if (count >= 500) {
                vo.setOverfiveHundredMine(vo.getOverStaffMine() + 1);
            }
        });
        vo.setCount(total.get());
        String leadSql = "select count(1) from dwd_jxry_now_personnelinfo where flag_bit='1' and mine_leader='1'";
        vo.setLead(locationJdbcTemplate.queryForObject(leadSql, Integer.class));
        StringBuffer overSql = new StringBuffer("SELECT count(mine_code) FROM \"dwd_jxry_base_overmanalarm\" " +
                "where  in_station_time>current_timestamp - interval '10 minutes' GROUP BY mine_code");
        try {
            vo.setOverStaffMine(locationJdbcTemplate.queryForObject(overSql.toString(), Integer.class));
        } catch (EmptyResultDataAccessException e) {
            vo.setOverStaffMine(0);
        }
        return vo;
    }

    public CompanyAlarmVo alarm() {
        CompanyAlarmVo vo = new CompanyAlarmVo();
        String helpSql = "SELECT * FROM \"dwd_jxry_base_cryinfo\" where cry_start_time>CURRENT_DATE";
        List<Map<String, Object>> helpMaps = locationJdbcTemplate.queryForList(helpSql);
        vo.setHelp(helpMaps.size());
        helpMaps.forEach(s -> {
            CompanyAlarmVo.Info info = vo.new Info();
            info.setAlarmType("人员求救");
            info.setBeginTime((Date) s.get("cry_start_time"));
            info.setMineName(Constants.mineCodeName.get(s.get("mine_code")));
            info.setStaffName(s.get("staff_name") + "");
            vo.getInfos().add(info);
        });
        String overSql = "SELECT * FROM \"dwd_jxry_base_overmanalarm\" where alarm_start_time>CURRENT_DATE";
        List<Map<String, Object>> overMaps = locationJdbcTemplate.queryForList(overSql);
        vo.setOverStaff(overMaps.size());
        overMaps.forEach(s -> {
            CompanyAlarmVo.Info info = vo.new Info();
            info.setAlarmType("超员报警");
            info.setBeginTime((Date) s.get("alarm_start_time"));
            info.setMineName(Constants.mineCodeName.get(s.get("mine_code")));
            info.setStaffName(s.get("area_staff") + "");
            vo.getInfos().add(info);
        });
        String timeOutSql = "SELECT * FROM \"dwd_jxry_base_timeoutalarm\" where alarm_start_time >CURRENT_DATE";
        List<Map<String, Object>> timeOutMaps = locationJdbcTemplate.queryForList(timeOutSql);
        vo.setOverTime(timeOutMaps.size());
        timeOutMaps.forEach(s -> {
            CompanyAlarmVo.Info info = vo.new Info();
            info.setAlarmType("超时报警");
            info.setBeginTime((Date) s.get("alarm_start_time"));
            info.setMineName(Constants.mineCodeName.get(s.get("mine_code")));
            info.setStaffName(s.get("staff_name") + "");
            vo.getInfos().add(info);
        });
        String limitAreaSql = "SELECT * FROM \"dwd_jxry_base_accessrestrictedarea\" where alarm_start_time>CURRENT_DATE";
        List<Map<String, Object>> limitMaps = locationJdbcTemplate.queryForList(limitAreaSql);
        vo.setRestrictedArea(limitMaps.size());
        limitMaps.forEach(s -> {
            CompanyAlarmVo.Info info = vo.new Info();
            info.setAlarmType("限制区域报警");
            info.setBeginTime((Date) s.get("alarm_start_time"));
            info.setMineName(Constants.mineCodeName.get(s.get("mine_code")));
            info.setStaffName(s.get("staff_name") + "");
            vo.getInfos().add(info);
        });
        return vo;
    }

    public CompanyRiskVo risk(String type) {
        Calendar calendar = Calendar.getInstance();
        Date endTime = calendar.getTime();
        if ("月".equals(type)) {
            calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
        } else {
            calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - 7);
        }
        List<String> xDate = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        while (calendar.getTime().getTime() <= endTime.getTime()) {
            xDate.add(sdf.format(calendar.getTime()));
            calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + 1);
        }
        CompanyRiskVo vo = new CompanyRiskVo();
        vo.setLeadMaxCount(new Integer[xDate.size()]);
        vo.setLeadNone(new Integer[xDate.size()]);
        vo.setMaxCount(new Integer[xDate.size()]);
        vo.setOverStaff(new Integer[xDate.size()]);
        String leadNoneSql = " select to_char(begin_time,'yyyy-mm-dd') as day,count(1) as count from dws_jxry_his_noleader_offduty_day where begin_time>'%s' GROUP BY day";
        List<Map<String, Object>> leadNoneMaps = locationJdbcTemplate.queryForList(String.format(leadNoneSql, xDate.get(0)));
        for (Map<String, Object> map : leadNoneMaps) {
            Integer[] leadNone = vo.getLeadNone();
            leadNone[xDate.indexOf(map.get("day"))] = Integer.parseInt(map.get("count") + "");
        }
        String overSql = "SELECT to_char(alarm_start_time,'yyyy-mm-dd') as day,count(1) as count FROM \"dwd_jxry_base_overmanalarm\" where alarm_start_time>'%s' GROUP BY day";
        List<Map<String, Object>> overMaps = locationJdbcTemplate.queryForList(String.format(overSql, xDate.get(0)));
        for (Map<String, Object> map : overMaps) {
            Integer[] overStaff = vo.getOverStaff();
            overStaff[xDate.indexOf(map.get("day"))] = Integer.parseInt(map.get("count") + "");
        }
        String maxCountSql = "SELECT SUBSTRING (hh,0,11) as day,max(count)  as count from (" +
                "SELECT  to_char(data_time,'yyyy-mm-dd hh') as hh,count(distinct(staff_code)) count FROM \"dwd_jxry_now_personnelinfo\" GROUP BY hh\n" +
                ")t GROUP BY day";
        List<Map<String, Object>> maxCountMaps = locationJdbcTemplate.queryForList(String.format(maxCountSql, xDate.get(0)));
        for (Map<String, Object> map : maxCountMaps) {
            Integer[] maxCount = vo.getMaxCount();
            maxCount[xDate.indexOf(map.get("day"))] = Integer.parseInt(map.get("count") + "");
        }
        String leadMaxCountSql = "SELECT SUBSTRING (hh,0,11) as day,max(count)  as count from (" +
                "SELECT  to_char(data_time,'yyyy-mm-dd hh') as hh,count(distinct(staff_code)) count FROM \"dwd_jxry_now_personnelinfo\" where mine_leader='1' GROUP BY hh\n" +
                ")t GROUP BY day";
        List<Map<String, Object>> leadMaxCountMaps = locationJdbcTemplate.queryForList(String.format(leadMaxCountSql, xDate.get(0)));
        for (Map<String, Object> map : leadMaxCountMaps) {
            Integer[] leadMaxCount = vo.getLeadMaxCount();
            leadMaxCount[xDate.indexOf(map.get("day"))] = Integer.parseInt(map.get("count") + "");
        }
        vo.setXData(xDate);
        return vo;
    }

    public Indicator getMineInfo(String mineCode) {
        R<MineVo> r = remoteMineInfoService.getMineInfo(mineCode);
        Indicator indicator = new Indicator();
        if (Constants.SUCCESS == r.getCode()) {
            indicator.setGasGrade(r.getData().getGasLevel() + "");
            indicator.setCombustion(r.getData().getCoalDustPyrophoric());
            indicator.setExplosive(r.getData().getCoalDustExplosion());
            indicator.setMineName(Constants.mineCodeName.get(mineCode));
            String sql = "select count(1) from dwd_jxry_now_personnelinfo where flag_bit='1' and mine_code='" + mineCode + "'";
            indicator.setPeopleNumber(locationJdbcTemplate.queryForObject(sql, Integer.class));
        }
        return indicator;
    }

    public PeopleTrendVo peopleTrend(String type, String companyCode) {
        PeopleTrendVo peopleTrendVo = new PeopleTrendVo();
        Calendar calendar = Calendar.getInstance();
        Date endTime = calendar.getTime();
        if ("月".equals(type)) {
            calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
        } else {
            calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - 7);
        }
        List<String> xDate = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        while (calendar.getTime().getTime() <= endTime.getTime()) {
            xDate.add(sdf.format(calendar.getTime()));
            calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + 1);
        }
        peopleTrendVo.setXData(xDate);
        peopleTrendVo.setCount(new int[xDate.size()]);
        peopleTrendVo.setLeadCount(new int[xDate.size()]);
        String sql = "SELECT number_people_max,to_char(data_time,'yyyy-mm-dd') FROM " +
                "\"dwd_jxry_miners_numberinfo\" where data_time>='%s' %s";
        if (org.apache.commons.lang3.StringUtils.isNotBlank(companyCode)) {
            companyCode = " and company_code='" + companyCode + "'";
        } else {
            companyCode = "";
        }
        List<Map<String, Object>> maps = locationJdbcTemplate.queryForList(String.format(sql, xDate.get(0), companyCode));
        maps.forEach(s -> {
            peopleTrendVo.getCount()[xDate.indexOf(s.get("to_char"))] = s.get("number_people_max") == null ? 0 : (int) s.get("number_people_max");
        });
        String leadSql = "SELECT  to_char(data_time, 'YYYY-MM-DD')  as day,count(distinct staff_code) as count  FROM \"dwd_jxry_his_personnelinfo\" where  data_time>'%s' and mine_leader='1' %s GROUP BY day";
        List<Map<String, Object>> maps1 = locationJdbcTemplate.queryForList(String.format(leadSql, xDate.get(0), companyCode));
        maps1.forEach(s -> {
            peopleTrendVo.getLeadCount()[xDate.indexOf(s.get("day"))] = s.get("count") == null ? 0 : (int) s.get("count");
        });
        StringBuffer currentCount = new StringBuffer("select count(1) from dwd_jxry_now_personnelinfo where flag_bit='1' %s ");
        peopleTrendVo.setCurrentCount(locationJdbcTemplate.queryForObject(String.format(currentCount.toString(), companyCode), Integer.class));
        StringBuffer leadCount = new StringBuffer("select count(1) from dwd_jxry_now_personnelinfo where flag_bit='1' and mine_leader='1' %s ");
        peopleTrendVo.setCurrentlead(locationJdbcTemplate.queryForObject(String.format(leadCount.toString(), companyCode), Integer.class));
        return peopleTrendVo;
    }
}
